package com.wzdigit.wms.wms.service.inv.count;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.base.Joiner;
import com.wzdigit.framework.Shift;
import com.wzdigit.framework.exception.RestStatusException;
import com.wzdigit.wms.basic.client.Pager;
import com.wzdigit.wms.basic.client.PagerInfo;
import com.wzdigit.wms.basic.client.response.Result;
import com.wzdigit.wms.basic.client.response.basic.SkuBaseResponse;
import com.wzdigit.wms.basic.domain.basic.*;
import com.wzdigit.wms.basic.domain.inventory.Goods;
import com.wzdigit.wms.basic.domain.inventory.LotAttrDtl;
import com.wzdigit.wms.basic.domain.inventory.Lotno;
import com.wzdigit.wms.basic.enums.GoodsStatusEnum;
import com.wzdigit.wms.basic.enums.WarehouseEnum;
import com.wzdigit.wms.basic.enums.inventory.count.dtl.InvDtlResultEnum;
import com.wzdigit.wms.basic.enums.inventory.count.dtl.InvDtlStatusEnum;
import com.wzdigit.wms.basic.enums.inventory.count.dtl.InvTaskTypeEnum;
import com.wzdigit.wms.basic.enums.inventory.count.goods.InvIsExitEnum;
import com.wzdigit.wms.basic.enums.inventory.count.header.InvHeaderResultEnum;
import com.wzdigit.wms.basic.enums.inventory.count.header.InvHeaderStatusEnum;
import com.wzdigit.wms.basic.enums.inventory.count.header.InvHeaderTypeEnum;
import com.wzdigit.wms.basic.enums.inventory.count.header.InvIsDynamicEnum;
import com.wzdigit.wms.basic.mapper.core.basic.*;
import com.wzdigit.wms.basic.mapper.core.inventory.GoodsMapper;
import com.wzdigit.wms.basic.service.SkuPermService;
import com.wzdigit.wms.basic.service.code.LotnoService;
import com.wzdigit.wms.basic.service.code.WhsPermService;
import com.wzdigit.wms.basic.util.HttpSessionUtil;
import com.wzdigit.wms.common.utils.SapWebServiceUtil;
import com.wzdigit.wms.web.service.common.wms2sap.ZDT_MsgHeader;
import com.wzdigit.wms.web.service.common.wms2sap.ZDT_Reserve;
import com.wzdigit.wms.web.service.wms2sap.storecheckproof.*;
import com.wzdigit.wms.wms.domain.dto.inv.count.*;
import com.wzdigit.wms.wms.domain.inv.count.*;
import com.wzdigit.wms.wms.mapper.InvCountBackResultMapper;
import com.wzdigit.wms.wms.mapper.inv.count.InvCountDtlGoodsMapper;
import com.wzdigit.wms.wms.mapper.inv.count.InvCountDtlMapper;
import com.wzdigit.wms.wms.mapper.inv.count.InvCountHeaderMapper;
import com.wzdigit.wms.wms.mapper.inv.count.InvCountScopeMapper;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.utils.BeanUtil;
import net.dreamlu.mica.core.utils.CollectionUtil;
import net.dreamlu.mica.core.utils.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
@Slf4j
public class StockCountDtlService {



    private static Pattern linePattern = Pattern.compile("_(\\w)");

    public final static String  NULL_LOC = "空库位";

    public final static Integer  NO_NEED_BACK = 1;

    public final static Integer  BACK_STATUS_NOBACK = 1;
    public final static Integer  BACK_STATUS_SUCCESS = 2;
    public final static Integer  BACK_STATUS_FAIL = 3;

    @Autowired
    InvCountHeaderMapper headerMapper ;

    @Autowired
    InvCountDtlMapper dtlMapper;

    @Autowired
    InvCountDtlGoodsMapper invCountDtlGoodsMapper;

    @Autowired
    SkuMapper skuMapper ;

    @Autowired
    GoodsMapper goodsMapper;

    @Autowired
    LotnoService lotnoService;

    @Autowired
    WarehouseMapper warehouseMapper;

    @Autowired
    SkuPermService skuPermService;

    @Autowired
    WhsPermService whsPermService;

    @Autowired
    LocationMapper locationMapper ;

    @Autowired
    ZoneMapper zoneMapper;
    @Autowired
    ZoneGroupMapper zoneGroupMapper ;

    @Autowired
    InvCountTaskService invCountTaskService;

    @Autowired
    InvCountBackResultMapper invCountBackResultMapper;

    @Autowired
    InvCountScopeMapper invCountScopeMapper;


    public InvCountTotalAndDetail selectCountDtlDetailList(InvCountDtlRequest detailRequest, String username, HttpServletRequest request) {
        //单据状态为审核通过并且盘点类型是动态库存 生成盘点任务
        InvCountHeader invCountHeader = headerMapper.selectById(detailRequest.getInvCountHeaderId());
        createTaskDetail(detailRequest, request, invCountHeader);

        InvCountTotalAndDetail invCountTotalAndDetail = new InvCountTotalAndDetail();
        //判断盘点单是属于材料还是成品
        List<Integer> whsIds = whsPermService.getWareHouseIds(username);

        Warehouse warehouse = warehouseMapper.selectById(invCountHeader.getWhsId());
        List<Integer> skuIds = null;
        if("1".equals(warehouse.getWhsType())&&detailRequest.getIsSelf()){//原材料仓
            //处理权限
            skuIds = skuPermService.getSkuIdPerm(username, whsIds);
            if(CollectionUtil.isEmpty(skuIds)){
                Shift.fatal("当前登录人没有配置物料权限！");
            }
        }
        QueryWrapper<InvCountDtl> wrapper = null;
        List<InvCountDtlCountResponse> list = dtlMapper.selectCount(detailRequest,skuIds);
        Integer notCompelateQty  = 0;
        for (InvCountDtlCountResponse item : list){
            //查询汇总状态,其中一条为未完成则为未完成状态
             wrapper= new QueryWrapper<>();
            wrapper.eq("INV_COUNT_HEADER_ID",detailRequest.getInvCountHeaderId());
            wrapper.eq("SKU_ID",item.getSkuId());
            wrapper.ne("STATUS", InvDtlStatusEnum.FINISH.code);

            List<InvCountDtl> unCompelateList = dtlMapper.selectList(wrapper);
            if(CollectionUtil.isNotEmpty(unCompelateList)){
                item.setStatus(InvDtlStatusEnum.ING.code);
                notCompelateQty++;
            }else{
                item.setStatus(InvDtlStatusEnum.FINISH.code);
            }

        }
        if(detailRequest.getIsCompelate()){
            list = list.stream().filter(l->l.getStatus()!=InvDtlStatusEnum.FINISH.code).collect(Collectors.toList());
        }
        invCountTotalAndDetail.setCountDtlCountResponseList(list);
        invCountTotalAndDetail.setTotalQty(list.size());
        invCountTotalAndDetail.setNotCompelateQty(notCompelateQty);
        return invCountTotalAndDetail;

    }

    private void createTaskDetail(InvCountDtlRequest detailRequest, HttpServletRequest request, InvCountHeader invCountHeader) {
        if(invCountHeader.getStatus()==InvHeaderStatusEnum.APPROVED.code&& invCountHeader.getDynamicInventory()== InvIsDynamicEnum.YES.code) {
            //查询是否已经有明细 ，有的话抛异常
            try {
                invCountTaskService.createCountTask(Arrays.asList(detailRequest.getInvCountHeaderId()), request);
            } catch(RestStatusException e){
                Shift.fatal(e.getContent());
            } catch(Exception e) {
                e.printStackTrace();
                Shift.fatal("生成盘点任务失败！");
            }
            invCountHeader.setStatus(InvHeaderStatusEnum.WAIT_INV.code);
            invCountHeader.setModifyTime(new Date());
            invCountHeader.setModifyUser(HttpSessionUtil.getLoginName(request));
            headerMapper.updateById(invCountHeader);
        }
    }

    @Transactional
    public Result submit(InvCountSubmitRequest request,String loginName) {
        List<InvCountDtl> invCountDtls = dtlMapper.selectBatchIds(request.getDtlIds());
        //非新建或者盘点中
        for (InvCountDtl invCountDtl : invCountDtls){
            if(invCountDtl.getStatus()!= InvDtlStatusEnum.CREATE.code&&invCountDtl.getStatus()!=InvDtlStatusEnum.ING.code){
                Shift.fatal(invCountDtl.getInvCountLineNo()+"行明细状态为【"+InvDtlStatusEnum.getEnumByCode(invCountDtl.getStatus()).getEnumName()+"】,无法提交");
            }
            invCountDtl.setStatus(InvDtlStatusEnum.FINISH.code);
            if(invCountDtl.getCountQty().compareTo(invCountDtl.getAccountQty())==-1){//实盘数小于账面数 盘亏
                invCountDtl.setResult(InvDtlResultEnum.LOSS.code);
            }else if(invCountDtl.getCountQty().compareTo(invCountDtl.getAccountQty())==0) {//实盘数等于账面数 正常
                invCountDtl.setResult(InvDtlResultEnum.NORMAL.code);
            }else if(invCountDtl.getCountQty().compareTo(invCountDtl.getAccountQty())==1){//实盘数大于账面数 盘盈
                invCountDtl.setResult(InvDtlResultEnum.PROFIT.code);
            }
            invCountDtl.setCountTime(new Date());
            invCountDtl.setCountBy(loginName);
            invCountDtl.setModifyTime(new Date());
            invCountDtl.setModifyUser(loginName);
            dtlMapper.updateById(invCountDtl);
            //更新goods状态 针对没有盘到的SN，更改状态为盘亏
            invCountDtlGoodsMapper.updateResultByDtlId(invCountDtl.getInvCountDtlId(),InvDtlResultEnum.LOSS.code,loginName);
        }


        //查询任务是否已经全部完成，全部完成更新主表状态
        QueryWrapper<InvCountDtl> wrapper = new QueryWrapper<>();
        //随便取一行
        wrapper.eq("INV_COUNT_HEADER_ID",invCountDtls.get(0).getInvCountHeaderId());
        wrapper.eq("RE_COUNT_ID",0);//最后一次盘点任务
        //wrapper.ne("STATUS",InvDtlStatusEnum.FINISH.code);
        List<InvCountDtl> allDtls = dtlMapper.selectList(wrapper);
        //判断是否所有明细都为已完成
           //更新主任务状态为完成
        InvCountHeader invCountHeader = headerMapper.selectById(invCountDtls.get(0).getInvCountHeaderId());
        invCountHeader.setCountBy(loginName);
        invCountHeader.setModifyUser(loginName);
        invCountHeader.setModifyTime(new Date());
        //提交了 不正常的
        List<InvCountDtl> notNormal = allDtls.stream().filter(item ->item.getResult()!=null&&item.getResult()!=InvDtlResultEnum.NORMAL.code).collect(Collectors.toList());
        //未提交结果的
        List<InvCountDtl> waitSubmit = allDtls.stream().filter(item ->item.getResult()==null).collect(Collectors.toList());

        if (CollectionUtil.isEmpty(waitSubmit)) {//明细结果全部提交，更新表头盘点结果更新表头状态
            if(request.getIsFirst()){//初盘
                invCountHeader.setStatus(InvHeaderStatusEnum.FINISH_INV.code);
            }else{
                invCountHeader.setStatus(InvHeaderStatusEnum.FINISH_REL_INV.code);
            }
            if(CollectionUtil.isNotEmpty(notNormal)){//有结果不正常的
                invCountHeader.setResult(InvHeaderResultEnum.DIF.code + "");
            }else{
                invCountHeader.setResult(InvHeaderResultEnum.NORMAL.code + "");
            }
        }else{//部分提交
            if(request.getIsFirst()){//初盘
                invCountHeader.setStatus(InvHeaderStatusEnum.ING_INV.code);
            }else{//复盘
                invCountHeader.setStatus(InvHeaderStatusEnum.ING_REL_INV.code);
            }

        }
        headerMapper.updateById(invCountHeader);
        return  new Result();
    }


    @Transactional
    public Result noEntitysubmit(InvCountSubmitRequest request,String loginName) {
        List<InvCountDtl> invCountDtls = dtlMapper.selectBatchIds(request.getDtlIds());
        //非新建或者盘点中
        for (InvCountDtl invCountDtl : invCountDtls){
            if(invCountDtl.getStatus()!= InvDtlStatusEnum.CREATE.code&&invCountDtl.getStatus()!=InvDtlStatusEnum.ING.code){
                Shift.fatal(invCountDtl.getInvCountLineNo()+"行明细状态为【"+InvDtlStatusEnum.getEnumByCode(invCountDtl.getStatus()).getEnumName()+"】,无法按无实物盘点处理");
            }
            invCountDtl.setStatus(InvDtlStatusEnum.ING.code);
          /*  if(invCountDtl.getCountQty().compareTo(invCountDtl.getAccountQty())==-1){//实盘数小于账面数 盘亏
                invCountDtl.setResult(InvDtlResultEnum.LOSS.code);
            }else if(invCountDtl.getCountQty().compareTo(invCountDtl.getAccountQty())==0) {//实盘数等于账面数 正常
                invCountDtl.setResult(InvDtlResultEnum.NORMAL.code);
            }else if(invCountDtl.getCountQty().compareTo(invCountDtl.getAccountQty())==1){//实盘数大于账面数 盘盈
                invCountDtl.setResult(InvDtlResultEnum.PROFIT.code);
            }*/
            invCountDtl.setCountTime(new Date());
            invCountDtl.setCountBy(loginName);
            invCountDtl.setModifyTime(new Date());
            invCountDtl.setModifyUser(loginName);
            dtlMapper.updateById(invCountDtl);
            //更新盘点goods状态
            invCountDtlGoodsMapper.updateResultByDtlId(invCountDtl.getInvCountDtlId(),InvDtlResultEnum.LOSS.code,loginName);

        }


        //查询任务是否已经全部完成，全部完成更新主表状态
        QueryWrapper<InvCountDtl> wrapper = new QueryWrapper<>();
        //随便取一行
        wrapper.eq("INV_COUNT_HEADER_ID",invCountDtls.get(0).getInvCountHeaderId());
        wrapper.eq("RE_COUNT_ID",0);//最后一次盘点任务
        //wrapper.ne("STATUS",InvDtlStatusEnum.FINISH.code);
        List<InvCountDtl> allDtls = dtlMapper.selectList(wrapper);
        //判断是否所有明细都为已完成
        List<InvCountDtl> noFinish = allDtls.stream().filter(item -> item.getStatus() != InvDtlStatusEnum.FINISH.code).collect(Collectors.toList());
        //更新主任务状态为完成
        InvCountHeader invCountHeader = headerMapper.selectById(invCountDtls.get(0).getInvCountHeaderId());
        if(CollectionUtil.isEmpty(noFinish)){
            //判断初盘还是复盘
            if(invCountHeader.getInvCountType()==InvTaskTypeEnum.ONCE_COUNT.code){
                invCountHeader.setStatus(InvHeaderStatusEnum.FINISH_INV.code);
            }else {
                invCountHeader.setStatus(InvHeaderStatusEnum.FINISH_REL_INV.code);
            }
        }
        //提交了 不正常的
        List<InvCountDtl> notNormal = allDtls.stream().filter(item ->item.getResult()!=null&&item.getResult()!=InvDtlResultEnum.NORMAL.code).collect(Collectors.toList());
        //未提交结果的
        List<InvCountDtl> waitSubmit = allDtls.stream().filter(item ->item.getResult()==null).collect(Collectors.toList());

        if (CollectionUtil.isEmpty(waitSubmit)) {//明细结果全部提交，更新表头盘点结果更新表头状态
            if(request.getIsFirst()){//初盘
                invCountHeader.setStatus(InvHeaderStatusEnum.FINISH_INV.code);
            }else{
                invCountHeader.setStatus(InvHeaderStatusEnum.FINISH_REL_INV.code);
            }
            if(CollectionUtil.isNotEmpty(notNormal)){//有结果不正常的
                invCountHeader.setResult(InvHeaderResultEnum.DIF.code + "");
            }else{
                invCountHeader.setResult(InvHeaderResultEnum.NORMAL.code + "");
            }
        }else{//部分提交
            if(request.getIsFirst()){//初盘
                invCountHeader.setStatus(InvHeaderStatusEnum.ING_INV.code);
            }else{//复盘
                invCountHeader.setStatus(InvHeaderStatusEnum.ING_REL_INV.code);
            }

        }
        headerMapper.updateById(invCountHeader);
        return  new Result();
    }



    @Transactional
    public Result recount(List<BigDecimal> dtlIds,String loginName) {
        List<InvCountDtl> returnList = new ArrayList<>();
        //获取盘点任务明细
        for(BigDecimal dtlId:dtlIds){
            InvCountDtl invCountDtl = dtlMapper.selectById(dtlId);
            //获取盘点任务主表

            //校验盘点任务明细
            if(invCountDtl.getStatus()!=InvDtlStatusEnum.ING.code){
                Shift.fatal("该明细状态为【"+InvDtlStatusEnum.getEnumByCode(invCountDtl.getStatus()).getEnumName()+"】,无法重新盘点");
            }
            //重置盘点任务实盘数量
            invCountDtl.setCountQty(BigDecimal.ZERO);
            invCountDtl.setModifyUser(loginName);
            invCountDtl.setModifyTime(new Date());
            invCountDtl.setStatus(InvDtlStatusEnum.CREATE.code);
            invCountDtl.setResult(null);
            dtlMapper.updateById(invCountDtl);
            //更新null值报错，没空研究 暂时直接更新
            dtlMapper.updateResultNull(invCountDtl.getInvCountDtlId());
            //重置盘点任务明细SN实盘数量为0和是否盘到更新为未盘到
            QueryWrapper<InvCountDtlGoods> queryWrapper = new QueryWrapper();
            queryWrapper.setEntity(new InvCountDtlGoods().setInvCountDtlId(dtlId));
            List<InvCountDtlGoods> list = invCountDtlGoodsMapper.selectList(queryWrapper);
            for(InvCountDtlGoods item : list){
                item.setIsExist(InvIsExitEnum.NO.code);
                item.setCountQty(BigDecimal.ZERO);
                item.setCountLoc(null);
                item.setModifyUser(loginName);
                item.setModifyTime(new Date());
                invCountDtlGoodsMapper.updateById(item);
            }
            returnList.add(invCountDtl);
        }
        Result result = new Result();
        result.setData(returnList);
        return result;
    }
    /**新增盘盈
        * @param countProfit
    	* @param loginName
        * @return com.wzdigit.wms.basic.client.response.Result
        * @author shuaic
        * @date 2021/10/13 10:06
    */
    @Transactional
    public Result addProfit(CountProfitRequest countProfit, String loginName)  {
        //盘点任务表头
        List<Integer> allowStatus = Arrays.asList(InvHeaderStatusEnum.WAIT_INV.code,
                InvHeaderStatusEnum.ING_INV.code,
                InvHeaderStatusEnum.WAIT_REL_INV.code,
                InvHeaderStatusEnum.ING_REL_INV.code);
        InvCountHeader invCountHeader = headerMapper.selectById(countProfit.getHeaderId());
        if(!allowStatus.contains(invCountHeader.getStatus())){
            Shift.fatal("盘点单状态为"+InvHeaderStatusEnum.getEnumByCode(invCountHeader.getStatus()).getEnumName()+",无法新增盘盈");
        }
        //物料
        SkuBaseResponse skuBaseResponse = skuMapper.selectOneBySkuCode(countProfit.getSkuCode());
        //库位
        Location location=null;
        if(StringUtil.isNotBlank(countProfit.getLocCode())&&!"null".equals(countProfit.getLocCode())){
            location = locationMapper.selectOneByLocCode(countProfit.getLocCode());//查询库位
            if(location==null){
                Shift.fatal("在系统未找到对应库位"+countProfit.getLocCode()+",请确认库位是否正确!");
            }
        }



        if(skuBaseResponse==null){
            Shift.fatal("该物料编码不存在");
        }
        //  SN料号必须在当前盘点范围
        QueryWrapper<InvCountDtl>  queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(new InvCountDtl().setInvCountHeaderId(countProfit.getHeaderId()).setSkuId(skuBaseResponse.getSkuId()));
        List<InvCountDtl> invCountDtls = dtlMapper.selectList(queryWrapper);
        if(CollectionUtil.isEmpty(invCountDtls)){
            Shift.fatal("该物料不在该任务盘点范围之内，无法新增盘盈");
        }


        //查询该任务下物料是否有SN(无SN则无SN管理)
        List<InvCountDtlGoods> countGoodsList = invCountDtlGoodsMapper.selectSnByHeaderId(countProfit.getHeaderId(),skuBaseResponse.getSkuId(),null,null);
        /*无SN管理
        1.物料盘点范围为所有物料、所有库位
        2.当前库位盘点任务中不存在该物料
        有SN管理
        1.Goods表中不存在或状态=1(新建)
        2.SN料号必须和当前盘点料号一致
        3.SN不在所有任务行的序号明细中
         */
        if(CollectionUtil.isEmpty(countGoodsList)){//无SN管理
            //判断盘点范围是否是包含所有物料 所有库位
           // QueryWrapper<InvCountScope> wrapper = new QueryWrapper<>();
           // wrapper.setEntity(new InvCountScope().setLoc("*").setSku("*"));
            List<InvCountScope> invCountScopes = invCountScopeMapper.selectAllScopes("*","*");
            if(CollectionUtil.isEmpty(invCountScopes)){
                Shift.fatal("当前盘点任务范围不为所有物料，所有库位，无法新增盘盈");
            }

            //根据库位和物料查询初盘任务里是否有该物料
            QueryWrapper<InvCountDtl>  wrapper= new QueryWrapper<>();
            queryWrapper.setEntity(new InvCountDtl()
                    .setLocId(location==null?null:location.getLocId())
                    .setInvCountHeaderId(countProfit.getHeaderId())
                    .setSkuId(skuBaseResponse.getSkuId())
                     .setTaskType(InvTaskTypeEnum.ONCE_COUNT.code));
            List<InvCountDtl> invCountDtlLoc = dtlMapper.selectList(wrapper);
            if(CollectionUtil.isNotEmpty(invCountDtlLoc)){
                Shift.fatal("该盘点单中对应的库位中有该物料的盘点任务，无法新增盘盈");
            }
        }else{
            //1.Goods表中不存在或状态=1(新建) 有SN管理
            Goods searchGoods = goodsMapper.selectBySn(countProfit.getGoodsSn());
            if(searchGoods!= null&&searchGoods.getStatus()!=GoodsStatusEnum.CREATE.code){
                Shift.fatal("该SN在仓库已经存在并且状态不为新建，无法新增盘盈");
            }

            //判断goodsSn是否在初盘盘点任务明细里面 不包含新增盘盈

            List<InvCountDtlGoods> invCountDtlGoods = invCountDtlGoodsMapper.selectSnByHeaderId(countProfit.getHeaderId(),null,countProfit.getGoodsSn(),InvDtlResultEnum.NEW_PROFIT.code);
            if(CollectionUtil.isNotEmpty(invCountDtlGoods)){
                Shift.fatal("该SN已经存在于盘点任务明细，无法新增");
            }


        }



        //获取生成批次号
        Lotno lotNo = null ;
        Warehouse warehouse = warehouseMapper.selectById(invCountHeader.getWhsId());
        if(warehouse.getWhsType()==3){//成品
            try {
                //构造一个goods
                Goods goods = addProfitGoods(countProfit, loginName, skuBaseResponse);
                //成品需要生成批次号
                lotNo= lotnoService.createLotnoByGoods(goods, loginName);
            } catch (Exception e) {
                Shift.fatal("生成批次号失败");
            }
        }

        //查询初盘任务


        //写入到盘点任务表
        //获取当前最大行号
        int lineNo =  dtlMapper.selectMaxLineNo(countProfit.getHeaderId())+1;
        InvCountDtl dtl = new InvCountDtl();
        dtl.setInvCountHeaderId(countProfit.getHeaderId());
        dtl.setInvCountLineNo(lineNo);
        dtl.setVendor(countProfit.getVender());
        dtl.setFactory(countProfit.getFactory());
        dtl.setSkuId(skuBaseResponse.getSkuId());
        dtl.setInvAttr(countProfit.getInvAttr().equals("S")?null:countProfit.getInvAttr());
        dtl.setQaStatus(countProfit.getQaStatus());
        dtl.setLotno(lotNo==null?null:lotNo.getLotno());
        dtl.setRelationTaskId(countProfit.getFirstDtlId());//上个任务ID，没有前端传0
        if(location!=null){
            dtl.setZoneId(location.getZoneId());
            Zone zone = zoneMapper.selectById(location.getZoneId());
            ZoneGroup zoneGroup = zoneGroupMapper.selectById(zone.getZoneGroupId());
            dtl.setLocId(location.getLocId());
        }

        dtl.setWhsId(invCountHeader.getWhsId());
        dtl.setAccountQty(BigDecimal.ZERO);
        dtl.setCountQty(countProfit.getQty());
        dtl.setResult(InvDtlResultEnum.NEW_PROFIT.code);
        dtl.setCountBy(loginName);
        dtl.setCountTime(new Date());
        dtl.setCreateTime(new Date());
        dtl.setCreateUser(loginName);
        if(countProfit.getIsFirst()){
            dtl.setTaskType(InvTaskTypeEnum.ONCE_COUNT.code);
        }else{
            dtl.setTaskType(InvTaskTypeEnum.RE_COUNT.code);
        }

        dtl.setReCountId(BigDecimal.ZERO);
        dtl.setUnit(skuBaseResponse.getBaseUnit());
        dtl.setStatus(InvDtlStatusEnum.FINISH.code);
        dtlMapper.insert(dtl);
        //查询上个任务，如果能查询到上个盘盈任务将这个任务的最后一次复盘ID更新成这个任务的ID
        InvCountDtl firstDtl = dtlMapper.selectById(countProfit.getFirstDtlId());
        if(firstDtl!=null) {
            firstDtl.setReCountId(dtl.getInvCountDtlId());
            firstDtl.setModifyTime(new Date());
            firstDtl.setModifyUser(loginName);
            dtlMapper.updateById(firstDtl);
        }


        //写入到盘点SN表
        //判断是否有SN
        if(CollectionUtil.isNotEmpty(countGoodsList)) {
            InvCountDtlGoods countDtlGoods = new InvCountDtlGoods();
            countDtlGoods.setInvCountDtlId(dtl.getInvCountDtlId());
            countDtlGoods.setGoodsSn(countProfit.getGoodsSn());
            countDtlGoods.setAccountQty(BigDecimal.ZERO);
            countDtlGoods.setCountQty(countProfit.getQty());
            if(location!=null){
                countDtlGoods.setCountLoc(location.getLocId());
            }
            countDtlGoods.setIsExist(InvIsExitEnum.YES.code);
            countDtlGoods.setResult(InvDtlResultEnum.NEW_PROFIT.code);
            countDtlGoods.setCountBy(loginName);
            countDtlGoods.setStatus(GoodsStatusEnum.CREATE.code);
            countDtlGoods.setCountTime(new Date());
            countDtlGoods.setCreateTime(new Date());
            countDtlGoods.setCreateUser(loginName);

            invCountDtlGoodsMapper.insert(countDtlGoods);
        }
        //更新表头状态
        int headerStatus = countProfit.getIsFirst()?InvHeaderStatusEnum.ING_INV.code:InvHeaderStatusEnum.ING_REL_INV.code;
        invCountHeader.setStatus(headerStatus);
        invCountHeader.setModifyTime(new Date());
        invCountHeader.setModifyUser(loginName);
        headerMapper.updateById(invCountHeader);
        return  new Result();

    }

    private Goods addProfitGoods(CountProfitRequest countProfit, String loginName, SkuBaseResponse skuBaseResponse) {
        Goods goods = new Goods();
        goods.setGoodsSn(countProfit.getGoodsSn());
        goods.setVendorId(countProfit.getVender());
        goods.setSkuId(skuBaseResponse.getSkuId());
        goods.setFactory(countProfit.getFactory());
        goods.setInvAttr(countProfit.getInvAttr());
        goods.setQaStatus(countProfit.getQaStatus());
        goods.setQty(countProfit.getQty());
       //goods.setWhsId(countProfit.getWhsId());
        goods.setStatus(GoodsStatusEnum.CREATE.code);
        goods.setCreateUser(loginName);
        goods.setCreateTime(new Date());
        //通过反射设置批次属性
        Map map = JSON.parseObject(countProfit.getLotNoJson().replace("\\",""), Map.class);
        Set<Map.Entry<String,String>> set = map.entrySet();
        for(Map.Entry<String,String> entry : set){
            Class<? extends Goods> clazz = goods.getClass();

            try {
                //获取属性 KEY转驼峰
                Field field = clazz.getDeclaredField(lineToHump(entry.getKey()));
                field.setAccessible(true);
                field.set(goods,entry.getValue());
            } catch (Exception e) {
                e.printStackTrace();
                Shift.fatal("设置批次属性值失败，系统异常");
            }
        }
        return goods;
    }

    /** 下划线转驼峰 */
    public static String lineToHump(String str) {
        str = str.toLowerCase();
        Matcher matcher = linePattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**实盘零差异
        * @param dtlId
    	* @param loginName
        * @return com.wzdigit.wms.basic.client.response.Result
        * @author shuaic
        * @date 2021/10/13 20:21
    */
    @Transactional
    public Result countNoDif(BigDecimal dtlId, String loginName) {
        //实盘零差异必须存在序号明细 状态为未盘点
        InvCountDtl invCountDtl = dtlMapper.selectById(dtlId);
        if(invCountDtl.getStatus()!=InvDtlStatusEnum.CREATE.code){
             Shift.fatal("盘点任务状态不为未盘点，操作失败");
        }
        //查询明细SN
        QueryWrapper<InvCountDtlGoods> wrapper = new QueryWrapper<>();
        wrapper.setEntity(new InvCountDtlGoods().setInvCountDtlId(dtlId));
        List<InvCountDtlGoods> invCountDtlGoods = invCountDtlGoodsMapper.selectList(wrapper);
        if(CollectionUtil.isEmpty(invCountDtlGoods)){
            Shift.fatal("该盘点任务没有明细SN，操作失败");
        }
        //更新该任务和明细SN的实盘数=账面数
        invCountDtl.setCountQty(invCountDtl.getAccountQty());
        //invCountDtl.setResult(InvDtlResultEnum.NORMAL.getCode());
        invCountDtl.setStatus(InvDtlStatusEnum.ING.code);
        invCountDtl.setCountBy(loginName);
        invCountDtl.setCountTime(new Date());
        invCountDtl.setModifyTime(new Date());
        invCountDtl.setModifyUser(loginName);
        dtlMapper.updateById(invCountDtl);
        for(InvCountDtlGoods item : invCountDtlGoods){
            item.setCountQty(item.getAccountQty());
            item.setIsExist(InvIsExitEnum.YES.code);
            item.setResult(InvDtlResultEnum.NORMAL.code);
            item.setModifyTime(new Date());
            item.setModifyUser(loginName);
            invCountDtlGoodsMapper.updateById(item);
        }

        return new Result();

    }
    @Transactional
    public Result countByWrite(BigDecimal dtlId, BigDecimal qty, String loginName) {
        //实盘零差异必须存在序号明细 状态为未盘点
        InvCountDtl invCountDtl = dtlMapper.selectById(dtlId);
        if(invCountDtl.getStatus()!=InvDtlStatusEnum.CREATE.code){
            Shift.fatal("盘点任务状态不为未盘点，操作失败");
        }
        //查询明细SN
        QueryWrapper<InvCountDtlGoods> wrapper = new QueryWrapper<>();
        wrapper.setEntity(new InvCountDtlGoods().setInvCountDtlId(dtlId));
        List<InvCountDtlGoods> invCountDtlGoods = invCountDtlGoodsMapper.selectList(wrapper);
        if(CollectionUtil.isNotEmpty(invCountDtlGoods)){
            Shift.fatal("该盘点任务有明细SN，操作失败");
        }
        //更新该任务状态和实盘数量
        invCountDtl.setCountQty(qty);
        /*if(qty.compareTo(invCountDtl.getAccountQty())==-1){//盘亏
            invCountDtl.setResult(InvDtlResultEnum.LOSS.code);
        }else if(qty.compareTo(invCountDtl.getAccountQty())==0){//正常
            invCountDtl.setResult(InvDtlResultEnum.NORMAL.code);
        }else{//盘亏
            invCountDtl.setResult(InvDtlResultEnum.PROFIT.code);
        }
        invCountDtl.setResult(InvDtlResultEnum.NORMAL.getCode());*/
        invCountDtl.setStatus(InvDtlStatusEnum.ING.code);
        invCountDtl.setModifyTime(new Date());
        invCountDtl.setModifyUser(loginName);
        dtlMapper.updateById(invCountDtl);

        return new Result();
    }

    /**按物料盘点结果汇总
        * @param headerId 盘点任务id
    	* @param skuCode  物料编码
    	* @param loginName 当前登录人
        * @return com.wzdigit.wms.wms.domain.dto.inv.count.InvCountDtlCountResponse
        * @author shuaic
        * @date 2021/10/14 11:05
    */
    public InvCountDtlCountResponse selectDetailCount(BigDecimal headerId, String skuCode, Boolean isFirst,String loginName) {

        //查询盘点任务明细
        InvCountDtlCountResponse response = new InvCountDtlCountResponse();
        SkuBaseResponse skuBaseResponse = skuMapper.selectOneBySkuCode(skuCode);
        QueryWrapper<InvCountDtl> wrapper = new QueryWrapper<>();
        if(isFirst){
            wrapper.setEntity(new InvCountDtl().setInvCountHeaderId(headerId).
                                                setSkuId(skuBaseResponse.getSkuId()).
                                                setTaskType(InvTaskTypeEnum.ONCE_COUNT.code));
        }else{
            //任务类型为复盘 且最后一次复盘ID为0 及其底下没有复盘任务
            wrapper.setEntity(new InvCountDtl().setInvCountHeaderId(headerId).
                                                setSkuId(skuBaseResponse.getSkuId()).
                                                setTaskType(InvTaskTypeEnum.RE_COUNT.code).
                                                setReCountId(BigDecimal.ZERO));
        }

        List<InvCountDtl> invCountDtls = dtlMapper.selectList(wrapper);

        //获取统计的数据
        //库位汇总数据 处理空库位
        Map<Integer,List<InvCountDtl>> map = invCountDtls.stream().collect(Collectors.groupingBy(item->{
            if(item.getLocId()==null){
                return  0;
            }else {
                return  item.getLocId();
            }
        }));
        List<Integer> locIds = map.keySet().stream().collect(Collectors.toList());
        List<Location> locations = locationMapper.selectBatchIds(locIds);
        List<String> locCodes = locations.stream().map(Location::getLocCode).collect(Collectors.toList());
        if(locIds.contains(0)){//处理空库位
            locCodes.add(NULL_LOC);
        }
        String locs = Joiner.on(",").join(locCodes);

        response.setLocCodes(locs);
        //账面数量
        setInvCountDtlCountResponse(response, invCountDtls);
        return  response;

    }

    /**按物料盘点结果汇总
        * @param headerId
    	* @param locCode
    	* @param loginName
        * @return com.wzdigit.wms.wms.domain.dto.inv.count.InvCountDtlCountResponse
        * @author shuaic
        * @date 2021/10/16 17:46
    */
    public InvCountDtlCountResponse selectDetailStockCount(BigDecimal headerId, String locCode, Boolean isFirst,String loginName) {
        //查询盘点任务明细
        InvCountDtlCountResponse response = new InvCountDtlCountResponse();
        Location location = locationMapper.selectOneByLocCode(locCode);
        QueryWrapper<InvCountDtl> wrapper = new QueryWrapper<>();
        wrapper.eq("INV_COUNT_HEADER_ID",headerId);
        //处理空库位
        if(NULL_LOC.equals(locCode)){
            wrapper.isNull("LOC_ID");
            response.setLocCodes(NULL_LOC);
        }else {
            wrapper.eq("LOC_ID",location.getLocId());
            response.setLocCodes(locCode);
        }

        if(isFirst){
            wrapper.eq("TASK_TYPE",InvTaskTypeEnum.ONCE_COUNT.code);
        }else{
            wrapper.eq("TASK_TYPE",InvTaskTypeEnum.RE_COUNT.code);
            wrapper.eq("RE_COUNT_ID",0);
        }

        List<InvCountDtl> invCountDtls = dtlMapper.selectList(wrapper);
        //获取统计的数据
        setInvCountDtlCountResponse(response, invCountDtls);

        return  response;

    }

    private void setInvCountDtlCountResponse(InvCountDtlCountResponse response, List<InvCountDtl> invCountDtls) {
        //账面数量
        BigDecimal accountQty = invCountDtls.stream().map(InvCountDtl::getAccountQty).reduce(BigDecimal.ZERO, BigDecimal::add);
        response.setAccountQty(accountQty);
        //实盘数量
        BigDecimal countQty = invCountDtls.stream().map(InvCountDtl::getCountQty).reduce(BigDecimal.ZERO, BigDecimal::add);
        response.setCountQty(countQty);
        //已完成数
        Integer compelateQty = invCountDtls.stream().filter(s -> s.getStatus() == InvDtlStatusEnum.FINISH.code).collect(Collectors.toList()).size();
        response.setCompelateQty(compelateQty);
        //总数
        Integer totalQty = invCountDtls.size();
        response.setTotalQty(totalQty);
        //正常项数
        Integer normalQty = invCountDtls.stream().filter(s -> s.getResult() != null && s.getResult() == InvDtlResultEnum.NORMAL.code).collect(Collectors.toList()).size();
        response.setNormalQty(normalQty);
        //盘亏项数
        Integer lossQty = invCountDtls.stream().filter(s -> s.getResult() != null && s.getResult() == InvDtlResultEnum.LOSS.code).collect(Collectors.toList()).size();
        response.setLossQty(lossQty);
        //盘盈项数
        Integer profitQty = invCountDtls.stream().filter(s -> s.getResult() != null && s.getResult() == InvDtlResultEnum.PROFIT.code).collect(Collectors.toList()).size();
        response.setProfitQty(profitQty);
        //新增盘盈项数
        Integer newProfitQty = invCountDtls.stream().filter(s -> s.getResult() != null && s.getResult() == InvDtlResultEnum.NEW_PROFIT.code).collect(Collectors.toList()).size();
        response.setNewProfitQty(newProfitQty);
    }


    public List<LotAttrDtl> getBatchAttr(Integer skuId,BigDecimal headerId) {
        //获取原材料仓库类型
        InvCountHeader invCountHeader = headerMapper.selectById(headerId);
        Warehouse warehouse = warehouseMapper.selectById(invCountHeader.getWhsId());
        //成品仓才有批次属性管控
        if(warehouse!=null&&warehouse.getWhsType()== WarehouseEnum.FINISHED_PRODUCT_WHS.code){
            List<LotAttrDtl> lotAttrDtls = null;
            try {
                lotAttrDtls = lotnoService.selectLotAttrDtlBySkuId(skuId);
                return lotAttrDtls;
            }catch (Exception e){
                e.printStackTrace();
                Shift.fatal("获取批次属性失败");
            }
            return  lotAttrDtls;
        }else{
            return null;
        }


    }

    /**按物料盘点明细数据
        * @param headerId
    	* @param skuCode
    	* @param status
    	* @param isFirst 是否初盘
        * @return java.util.List<com.wzdigit.wms.wms.domain.dto.inv.count.InvCountDtlResponse>
        * @author shuaic
        * @date 2021/10/18 20:52
    */
    public List<InvCountDtlResponse> selectDetailList(BigDecimal headerId, String skuCode, Integer status,Boolean isFirst) {
        //skuCode

        List<InvCountDtlResponse> list  =   dtlMapper.selectDetailList(headerId,  skuCode,  status,isFirst);
        //查询是否有SN管理
        Boolean hasSn = hasSn(headerId, skuCode).getHasSn();
        for(InvCountDtlResponse item:list){
            item.setHasSn(hasSn);
        }
        return  list;

    }

    /**按库位盘点明细数据
     * @param headerId
     * @param locCode
     * @param status
     * @param isFirst 是否初盘
     * @return java.util.List<com.wzdigit.wms.wms.domain.dto.inv.count.InvCountDtlResponse>
     * @author shuaic
     * @date 2021/10/18 20:52
     */
    public List<InvCountDtlResponse> selectStockDetailList(BigDecimal headerId, String locCode, Integer status,Boolean isFirst) {

        List<InvCountDtlResponse> list  =   dtlMapper.selectStockDetailList(headerId,  locCode,  status,isFirst);
        //查询是否有SN

        for(InvCountDtlResponse item:list){
            Boolean hasSn = hasSn(headerId, item.getSkuCode()).getHasSn();
            item.setHasSn(hasSn);
        }
        return  list;

    }


    public InvCountTotalAndDetail selectCountDtlStockList(InvCountDtlRequest detailRequest, String username,HttpServletRequest request) {
        //生成盘点任务
        InvCountHeader invCountHeader = headerMapper.selectById(detailRequest.getInvCountHeaderId());
        createTaskDetail(detailRequest, request, invCountHeader);
        InvCountTotalAndDetail invCountTotalAndDetail = new InvCountTotalAndDetail();
        //判断盘点单是属于材料还是成品
        List<Integer> whsIds = whsPermService.getWareHouseIds(username);
        Warehouse warehouse = warehouseMapper.selectById(invCountHeader.getWhsId());
        List<Integer> zoneIds = null;
        if(warehouse.getWhsType()==3){//成品
             zoneIds = whsPermService.getZonePerm(username);
             if(CollectionUtil.isEmpty(zoneIds)){
                 Shift.fatal("无相关任务信息!");
             }
        }
        QueryWrapper<InvCountDtl> wrapper = null;
        List<InvCountDtlCountResponse> list = dtlMapper.selectCountStock(detailRequest,whsIds,zoneIds);
        Integer notCompelateQty = 0 ;
        for (InvCountDtlCountResponse item : list){
            //查询汇总状态,其中一条为未完成则为未完成状态
            wrapper= new QueryWrapper<>();
            wrapper.eq("INV_COUNT_HEADER_ID",detailRequest.getInvCountHeaderId());
            if(item.getLocId()==null){
                wrapper.isNull("LOC_ID");
            }else{
                wrapper.eq("LOC_ID",item.getLocId());
            }
            wrapper.ne("STATUS", InvDtlStatusEnum.FINISH.code);
            List<InvCountDtl> unCompelateList = dtlMapper.selectList(wrapper);
            if(CollectionUtil.isNotEmpty(unCompelateList)){
                item.setStatus(InvDtlStatusEnum.ING.code);
                notCompelateQty++;
            }else{
                item.setStatus(InvDtlStatusEnum.FINISH.code);
            }



        }
        invCountTotalAndDetail.setCountDtlCountResponseList(list);
        invCountTotalAndDetail.setTotalQty(list.size());
        invCountTotalAndDetail.setNotCompelateQty(notCompelateQty);
        return invCountTotalAndDetail;

    }
    /**判断物料是否有SN
        * @param headerId
    	* @param skuCode
        * @return java.lang.Boolean
        * @author shuaic
        * @date 2021/10/18 11:02
    */
    public HasAndSnResponse hasSn(BigDecimal headerId, String skuCode) {
        HasAndSnResponse response = new HasAndSnResponse();
        SkuBaseResponse skuBaseResponse = skuMapper.selectOneBySkuCode(skuCode);
        if(skuBaseResponse==null) {
            Shift.fatal("未查到物料信息，请确认输入的物料编码是否正确");
        }
        List<InvCountDtlGoods> countGoodsList = invCountDtlGoodsMapper.selectSnByHeaderId(headerId, skuBaseResponse.getSkuId(),null,null);
        response.setHasSn(CollectionUtil.isNotEmpty(countGoodsList));
        response.setSkuId(skuBaseResponse.getSkuId());
        response.setSkuCode(skuBaseResponse.getSkuCode());
        response.setSkuDescCn(skuBaseResponse.getDescCn());
        return response;
    }

    /** 复盘获取新增盘盈SN历史记录
        * @param sn
        * @return com.wzdigit.wms.wms.domain.dto.inv.count.CountProfitResponse
        * @author shuaic
        * @date 2021/10/18 11:51
    */
    public CountProfitResponse firstprofitInfo(BigDecimal headerId, String sn) {
        //获取历史盘盈数据
        List<InvCountDtlGoods> invCountDtlGoods = invCountDtlGoodsMapper.selectSnByHeaderId(headerId, null,sn,null);
        //未查询到返回空
        if(CollectionUtil.isEmpty(invCountDtlGoods)){
            return  null;
        }
        InvCountDtlGoods countDtlGoods = invCountDtlGoods.get(0);
        //查询明细任务
        InvCountDtl invCountDtl = dtlMapper.selectById(countDtlGoods.getInvCountDtlId());



        CountProfitResponse response =   new CountProfitResponse();
        response.setFactory(invCountDtl.getFactory());
        response.setGoodsSn(countDtlGoods.getGoodsSn());
        response.setHeaderId(headerId);
        response.setInvAttr(invCountDtl.getInvAttr()==null?"S":invCountDtl.getInvAttr());
        if(invCountDtl.getLocId()!=null){
            Location location = locationMapper.selectById(invCountDtl.getLocId());
            response.setLocCode(location.getLocCode());
        }
        //获取批次属性
        Lotno lotno = null;
        if(invCountDtl.getLotno()!=null){
            lotno = lotnoService.selectByLotno(invCountDtl.getLotno());
        }
        if(lotno!=null){
            response.setLotAttr(lotno.getLotAttr());
            response.setLotAttrCode(lotno.getLotAttrCode());
        }
        response.setVender(invCountDtl.getVendor());
        response.setQaStatus(invCountDtl.getQaStatus());
        response.setQty(invCountDtl.getCountQty());
        Sku sku = skuMapper.selectById(invCountDtl.getSkuId());
        response.setSkuCode(sku.getSkuCode());
        response.setFirstDtlId(invCountDtl.getInvCountDtlId());
        return response;
    }

    public InvCountDtlResponse detailInfo(BigDecimal dtlId) {
        InvCountDtlResponse invCountDtlResponse  =   dtlMapper.selectDetailInfo(dtlId);
        Boolean hasSn = hasSn(invCountDtlResponse.getInvCountHeaderId(), invCountDtlResponse.getSkuCode()).getHasSn();
        invCountDtlResponse.setHasSn(hasSn);
        return invCountDtlResponse;
    }


    /** 盘点单差异统计列表
     * @param invCountNo
     * @param pager
     * @return com.wzdigit.wms.basic.client.PagerInfo<java.util.List<com.wzdigit.wms.wms.domain.dto.inv.count.InvCountHeaderResponse>>
     * @author shuaic
     * @date 2021/10/21 10:32
     */
    public PagerInfo<InvCountSapDifCountResponse> invCountDetailCountPageList(String invCountNo,Integer backStatus, Pager<?> pager) {
        InvCountSapDifCountResponse response = new InvCountSapDifCountResponse();
        //获取表头
        QueryWrapper<InvCountHeader> wrapper = new QueryWrapper<>();
        wrapper.setEntity(new InvCountHeader().setInvCountNo(invCountNo));
        InvCountHeader invCountHeader = headerMapper.selectOne(wrapper);
        response.setInvCountName(invCountHeader.getInvCountName());

        response.setInvCountType( InvHeaderTypeEnum.getEnumByCode(invCountHeader.getInvCountType()).getEnumName());
        //查询回传结果
        List<String> resultList  = invCountBackResultMapper.selectResult(invCountHeader);
        if(CollectionUtil.isEmpty(resultList)){
            response.setResult("未回传");
        }else{
            if(resultList.contains("E")){
                response.setResult("回传失败");
            }else{
                response.setResult("回传成功");
            }
        }

        //获取盘点单明细

        Page<?> page = PageHelper.offsetPage(pager.getSkipCount(), pager.getMaxResultCount());
        PagerInfo<InvCountSapDifCountResponse> pagerInfo = new PagerInfo<>();
        List<InvCountSapDifResponse>  list= invCountBackResultMapper.selectAllInfo(invCountNo,backStatus);
        response.setList(list);
        pagerInfo.setTotalCount(page.getTotal());
        pagerInfo.setItems(response);
        return  pagerInfo;
    }
    /**设置物料不回传SAP 假删，更改回传标识 IS_NEED_BACK
        * @param invCountSapDifRequests
        * @return com.wzdigit.wms.basic.client.response.Result
        * @author shuaic
        * @date 2021/10/21 16:13
    */
    @Transactional
    public Result invCountDtlDelete(List<InvCountSapDifRequest> invCountSapDifRequests) {
        for (InvCountSapDifRequest invCountSapDifRequest :invCountSapDifRequests){
            dtlMapper.updateDtlBySapDifRequest(invCountSapDifRequest,NO_NEED_BACK);
        }
        return  new Result();
    }


    @Value("${sap.web.service.protocol-head}")
    private String protocolHead;

    @Value("${sap.web.service.storeChekcProof-url}")
    private String uri;

    @Value("${wzdigit.web.service.sap.ip}")
    private String ip;

    /**回传SAP
        * @param invCountNo
        * @return com.wzdigit.wms.basic.client.response.Result
        * @author shuaic
        * @date 2021/10/22 11:05
    */
    public Result difBackToSap(String invCountNo,String loginName) {

        //查询数据
        List<InvCountSapDifResponse>  list= invCountBackResultMapper.selectAllInfo(invCountNo,null);
        //设置数据
        List<ZDT_071_1_ReqRECORDS> records = new ArrayList<>();
        for (InvCountSapDifResponse item : list){
            ZDT_071_1_ReqRECORDS record = new  ZDT_071_1_ReqRECORDS();
            record.setAEDAT(DateUtil.format(new Date(),"yyyyMMdd"));
            record.setWERKS(item.getFactory());
            record.setLGORT(item.getSapWareHourse());
            record.setSOBKZ("");
            record.setKDAUF("");
            record.setKDPOS("");
            record.setMATNR(item.getSkuCode());
            record.setMEINS(item.getUnit());
            record.setMENGE(item.getQty());
            ZDT_Reserve zr = new ZDT_Reserve();
            zr.setRsv2(item.getInvCountNo());//WMS盘点单号
            record.setRSV1(zr);
            records.add(record);

        }
        //回传SAP，回写回传结果
        log.info("开始调【SAP库存盘点凭证接口】");
        //发送【向SAP回传】的路径
        String urlString = protocolHead + ip + uri;

        log.info("发送报文的路径:" + urlString);

        ZSI_071_1_WMS2SAP_OutProxy proxy = new ZSI_071_1_WMS2SAP_OutProxy();

        proxy.setEndpoint(urlString);

        log.info("ZSI_071_1_WMS2SAP_OutProxy:" + proxy.toString());

        // 消息头
        ZDT_MsgHeader header = SapWebServiceUtil.getHeader();

        log.info("header:" + header);


        //输出请求的核心报文//


        ZDT_071_1_Req req = new ZDT_071_1_Req();

        // 消息头
        req.setHEADER(header);
        // 记录
        ZDT_071_1_ReqRECORDS [] reqRECORDS =records.toArray(new ZDT_071_1_ReqRECORDS [records.size()]);
        req.setRECORDS(reqRECORDS);

        ZDT_071_1_Rsp rsp = null;


        try {
            //调接口
            rsp = proxy.ZSI_071_WMS2SAP_Out(req);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        ZDT_071_1_RspRECORDS[] rspArr = rsp.getRECORDS();
        log.info(rspArr.toString());
        if(rspArr.length!=list.size()){
            Shift.fatal("SAP返回信息行数和WMS传的行数不一致，回传异常！！");
        }

        //处理返回的数据 删除旧的记录(根据盘点单号)，插入新的记录
        invCountBackResultMapper.delete(new QueryWrapper<InvCountBackResult>().setEntity(new InvCountBackResult().setInvCountNo(invCountNo)));

        try {
            for (int i = 0;i<rspArr.length;i++){
                ZDT_071_1_RspRECORDS record = rspArr[i];
                InvCountSapDifResponse response = list.get(i);
                InvCountBackResult result = new InvCountBackResult();
                BeanUtil.copyNonNull(response,result);
                result.setResult(record.getMSG_TYPE());
                result.setReason(record.getMESSAGE());
                result.setCreateTime(new Date());
                result.setCreateUser(loginName);
                result.setSapProof(record.getIBLNR());
                result.setSapProofLineno(record.getZEILI());
                invCountBackResultMapper.insert(result);

            }

        } catch (Exception e) {
            e.printStackTrace();
            log.error("转成XML出错");
        }
        return  new Result();
    }

    public PagerInfo<List<String>> invCountNoList(String invCountNo, Pager<?> pager) {

        Page<?> page = PageHelper.offsetPage(pager.getSkipCount(), pager.getMaxResultCount());
        PagerInfo<List<String>> pagerInfo = new PagerInfo<>();
        List<Integer> statusList = Arrays.asList(InvHeaderStatusEnum.FINISH_DIVERSITY.code, InvHeaderStatusEnum.CLOSE.code);
        List<String>  list= headerMapper.selectInvCountNoList(invCountNo,statusList);
        pagerInfo.setTotalCount(page.getTotal());
        pagerInfo.setItems(list);
        return  pagerInfo;
    }

    public Result getSkucodeBySn(String sn) {
        String skuCode = goodsMapper.getSkucodeBySn(sn);
        Result result = new Result();
        result.setData(skuCode);
        return  result;
    }
}
